package cn.xuqiudong.sso.server.storage;


import cn.xuqiudong.sso.server.constant.SsoServerConstant;
import cn.xuqiudong.sso.server.storage.model.LocalData;
import cn.xuqiudong.sso.server.storage.model.LocalDataCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;

/**
 * 描述:
 *      本地存储策略
 * @author Vic.xu
 * @since 2021-11-08 8:37
 */
@Component
@ConditionalOnProperty(name = SsoServerConstant.STORAGE_STRATEGY, havingValue = SsoServerConstant.LOCAL_MANAGER, matchIfMissing = true)
public class LocalStorageStrategy<T> implements StorageStrategy<T> {

    private Logger logger = LoggerFactory.getLogger(LocalStorageStrategy.class);

    /**
     * 每5分钟执行一次
     */
    public static final String CLEAN_CRON = "0 */5 * * * ?";

    @Override
    public void storage(String cacheName, String key, T data, int expire) {
        LocalData<T> localData = new LocalData<T>(data, expire);
        LocalDataCache.cache(cacheName, key, localData);
    }

    @Override
    public T getData(String cacheName, String key, Class<T> clazz) {
        LocalData<T> localData = LocalDataCache.get(cacheName, key);
        if (localData == null || localData.isExpire()) {
            return null;
        }
        return localData.getData();
    }


    @Override
    public T refresh(String cacheName, String key, int expire, Class<T> clazz) {
        LocalData<T> localData = LocalDataCache.get(cacheName, key);
        if (localData == null || localData.isExpire()) {
            return null;
        }
        localData.refresh();
        return localData.getData();
    }

    @Override
    public T remove(String cacheName, String key, Class<T> clazz) {
        LocalData<T> remove = LocalDataCache.remove(cacheName, key);
        return remove.getData();
    }

    @Override
    public void storage2SetData(String cacheName, String key, String data) {
        LocalData<HashSet> localData = LocalDataCache.get(cacheName, key);
        if (localData == null) {
            HashSet<String> set = new HashSet<>();
            set.add(data);
            localData = new LocalData<HashSet>(set, 8 * 60 * 60);
            LocalDataCache.cache(cacheName, key, localData);
        } else {
            HashSet hashSet = localData.getData();
            hashSet.add(data);
            localData.refresh();
        }
    }

    @Override
    public Set<String> getSetData(String cacheName, String key) {
        LocalData<HashSet> localData = LocalDataCache.get(cacheName, key);
        return localData.getData();
    }

    @Override
    @Scheduled(cron = CLEAN_CRON)
    public void cleanSchedule() {
        logger.info("start clean local data");
        LocalDataCache.checkAndExpire();
    }


}
